package com.jxmobi.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * @author Xiaofei Chen <a href="mailto:xchen@jxmobi.com">Email the author</a>
 * @version 1.0 5/17/16
 */
public abstract class CollectionUtils {
    private static final Logger log = LoggerFactory.getLogger(CollectionUtils.class);

    public static <T> boolean isEmpty(Collection<T> collection) {
        return (collection == null || collection.isEmpty());
    }

    public static boolean isEmpty(Map<?, ?> map) {
        return (map == null || map.isEmpty());
    }

    /**
     *  生成二元 pair，可以用于构建key-key-value的Map
     * @param first
     * @param second
     * @param <U>
     * @param <V>
     * @return
     */
    public static <U, V> Pair<U, V> newPairInstance(U first, V second) {
        return new Pair<U, V>(first, second);
    }

    /**
     *  将一个 List 按照特定的唯一的 key ，转换为 Map
     * @param list 待转换的集合
     * @param mapper 如何转化
     * @param <K> 对象的唯一性的 key
     * @param <T> 待转换的对象
     * @return key-对象 的 Map
     */
    public static <K, T> Map<K, T> toMapBy(List<T> list, Function<? super T, ? extends K> mapper) {
        return list.stream().collect(Collectors.toMap(mapper, Function.identity()));
    }

    /**
     *  sorting Lists after groupingBy
     * @param c comparator
     * @param <T>
     * @return
     */
    public static <T> Collector<T,?,List<T>> toSortedList(Comparator<? super T> c) {
        return Collectors.collectingAndThen(
                Collectors.toCollection(ArrayList::new), l->{ l.sort(c); return l; } );
    }

    /**
     *  transform an Iterable<E> to Collection<E>
     *
     * @param iter iterable
     * @param <E> element type
     * @return target collection
     */
    public static <E> Collection<E> makeCollection(Iterable<E> iter) {
        Collection<E> list = new ArrayList<E>();
        for (E item : iter) {
            list.add(item);
        }
        return list;
    }
}
